////////////////////////////////////////////////////////////////////////
//
// a1.cpp
//
// The first assignment for Advanced Multimedia Computing
//
// T. Kostelijk & F. Huizinga
//     0418889      0418862
//
////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>

int trackBarBlurVal = 1;
IplImage *blur      = 0; 
IplImage *gray      = 0; 
IplImage *scaled    = 0; 
IplImage *blurrgb   = 0;
IplImage *rgb       = 0; 

CvVideoWriter *writer = 0;
CvFont font;

// Overlay scaled rgb image and text
void overlayMetaData() {
    // convert to rgb (note image still stays gray)
    cvCvtColor(blur, blurrgb, CV_GRAY2RGB);

    // insert rgb scaled into blurred gray img
    uchar *data      = (uchar*) blurrgb->imageData;
    uchar *rgbscaled = (uchar*) scaled->imageData;
    int i,j,k,step   = scaled->widthStep, channels = scaled->nChannels;
    for(i=0;i<scaled->height;i++) for(j=0;j<scaled->width;j++) for(k=0;k<channels;k++)
        data[k+i*blurrgb->widthStep+j*channels]=rgbscaled[k+i*step+j*channels];

    // Draw filled rectangle
    cvRectangle(blurrgb, cvPoint(2,blurrgb->height-30), cvPoint(230, blurrgb->height-2), CV_RGB(0,0,0), CV_FILLED);

    // Give it text
    cvPutText(blurrgb, "F. Huizinga & T. Kostelijk", cvPoint(10,blurrgb->height-10), &font, CV_RGB(200,200,200));
}

void adjustBlur(int trackBarBlurVal) {
    int blurVal = 2*trackBarBlurVal+1;

    // Blur the image
    cvSmooth(gray, blur, CV_GAUSSIAN, blurVal, 0);

    // Overlay scaled rgb image and text
    overlayMetaData();

    // Repaint result
    cvShowImage("mainWin", blurrgb );

    // Append frame to video
    cvWriteFrame(writer, blurrgb);
}

int main(int argc, char *argv[])
{
    IplImage      *morphedrgb = 0;
    IplConvKernel *element    = 0;

    if(argc<3){
        printf("Usage: %s <image-file-name> <out-file-name.avi>\n\7", argv[0]);
        exit(0);
    }

    // load an image    
    rgb=cvLoadImage(argv[1]);
    if(!rgb){
        printf("Could not load image file: %s\n",argv[1]);
        exit(0);
    }

    // Create the font
    cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8);

    // Init writer
    writer = cvCreateVideoWriter(argv[2], CV_FOURCC('D','I','V','X'), 1, cvSize(rgb->width,rgb->height), 1);

    // Create structuring element
    element = cvCreateStructuringElementEx(5,5,0,0,CV_SHAPE_RECT,NULL);

    // Morphological operation
    morphedrgb = cvCreateImage(cvSize(rgb->width, rgb->height), rgb->depth, rgb->nChannels);
    cvErode(rgb, morphedrgb, element, 1);

    // convert to gray
    gray = cvCreateImage(cvSize(rgb->width, rgb->height), rgb->depth, 1);
    cvCvtColor(morphedrgb, gray, CV_RGB2GRAY);

    // scale image
    scaled = cvCreateImage(cvSize(rgb->width/8, rgb->height/8), rgb->depth, rgb->nChannels);
    cvResize(rgb, scaled);

    // create image blur
    blur = cvCreateImage(cvSize(gray->width, gray->height), gray->depth, 1);

    // create image blurrgb (still gray, but more channels)
    blurrgb = cvCreateImage(cvSize(rgb->width, rgb->height), rgb->depth, rgb->nChannels);

    // initialize image
    adjustBlur(trackBarBlurVal);

    // create a window
    cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE); 
    cvMoveWindow("mainWin", 100, 100);

    // show the image
    cvShowImage("mainWin", blurrgb );
    
    // create the trackbar (blur slider)
    cvCreateTrackbar( "Blur",  "mainWin", &trackBarBlurVal, 2, adjustBlur);

    // wait for a key
    cvWaitKey(0);

    // release the memory
    cvReleaseImage(&blur); 
    cvReleaseImage(&gray); 
    cvReleaseImage(&scaled); 
    cvReleaseImage(&blurrgb);
    cvReleaseImage(&rgb); 
    cvReleaseImage(&morphedrgb);
    cvReleaseStructuringElement(&element);
    cvReleaseVideoWriter(&writer);
    return 0;
}
